home *** CD-ROM | disk | FTP | other *** search
/ Clickx 115 / Clickx 115.iso / software / tools / windows / tails-i386-0.16.iso / live / filesystem.squashfs / usr / share / tcltk / tk8.5 / choosedir.tcl < prev    next >
Encoding:
Text File  |  2009-11-17  |  9.5 KB  |  311 lines

  1. # choosedir.tcl --
  2. #
  3. #    Choose directory dialog implementation for Unix/Mac.
  4. #
  5. # Copyright (c) 1998-2000 by Scriptics Corporation.
  6. # All rights reserved.
  7. # RCS: @(#) $Id: choosedir.tcl,v 1.23 2007/12/13 15:26:27 dgp Exp $
  8.  
  9. # Make sure the tk::dialog namespace, in which all dialogs should live, exists
  10. namespace eval ::tk::dialog {}
  11. namespace eval ::tk::dialog::file {}
  12.  
  13. # Make the chooseDir namespace inside the dialog namespace
  14. namespace eval ::tk::dialog::file::chooseDir {
  15.     namespace import -force ::tk::msgcat::*
  16. }
  17.  
  18. # ::tk::dialog::file::chooseDir:: --
  19. #
  20. #    Implements the TK directory selection dialog.
  21. #
  22. # Arguments:
  23. #    args        Options parsed by the procedure.
  24. #
  25. proc ::tk::dialog::file::chooseDir:: {args} {
  26.     variable ::tk::Priv
  27.     set dataName __tk_choosedir
  28.     upvar ::tk::dialog::file::$dataName data
  29.     Config $dataName $args
  30.  
  31.     if {$data(-parent) eq "."} {
  32.         set w .$dataName
  33.     } else {
  34.         set w $data(-parent).$dataName
  35.     }
  36.  
  37.     # (re)create the dialog box if necessary
  38.     #
  39.     if {![winfo exists $w]} {
  40.     ::tk::dialog::file::Create $w TkChooseDir
  41.     } elseif {[winfo class $w] ne "TkChooseDir"} {
  42.     destroy $w
  43.     ::tk::dialog::file::Create $w TkChooseDir
  44.     } else {
  45.     set data(dirMenuBtn) $w.contents.f1.menu
  46.     set data(dirMenu) $w.contents.f1.menu.menu
  47.     set data(upBtn) $w.contents.f1.up
  48.     set data(icons) $w.contents.icons
  49.     set data(ent) $w.contents.f2.ent
  50.     set data(okBtn) $w.contents.f2.ok
  51.     set data(cancelBtn) $w.contents.f2.cancel
  52.     set data(hiddenBtn) $w.contents.f2.hidden
  53.     }
  54.     if {$::tk::dialog::file::showHiddenBtn} {
  55.     $data(hiddenBtn) configure -state normal
  56.     grid $data(hiddenBtn)
  57.     } else {
  58.     $data(hiddenBtn) configure -state disabled
  59.     grid remove $data(hiddenBtn)
  60.     }
  61.  
  62.     # When using -mustexist, manage the OK button state for validity
  63.     $data(okBtn) configure -state normal
  64.     if {$data(-mustexist)} {
  65.     $data(ent) configure -validate key \
  66.         -validatecommand [list ::tk::dialog::file::chooseDir::IsOK? $w %P]
  67.     } else {
  68.     $data(ent) configure -validate none
  69.     }
  70.  
  71.     # Dialog boxes should be transient with respect to their parent,
  72.     # so that they will always stay on top of their parent window.  However,
  73.     # some window managers will create the window as withdrawn if the parent
  74.     # window is withdrawn or iconified.  Combined with the grab we put on the
  75.     # window, this can hang the entire application.  Therefore we only make
  76.     # the dialog transient if the parent is viewable.
  77.  
  78.     if {[winfo viewable [winfo toplevel $data(-parent)]] } {
  79.     wm transient $w $data(-parent)
  80.     }
  81.  
  82.     trace add variable data(selectPath) write \
  83.         [list ::tk::dialog::file::SetPath $w]
  84.     $data(dirMenuBtn) configure \
  85.         -textvariable ::tk::dialog::file::${dataName}(selectPath)
  86.  
  87.     set data(filter) "*"
  88.     set data(previousEntryText) ""
  89.     ::tk::dialog::file::UpdateWhenIdle $w
  90.  
  91.     # Withdraw the window, then update all the geometry information
  92.     # so we know how big it wants to be, then center the window in the
  93.     # display and de-iconify it.
  94.  
  95.     ::tk::PlaceWindow $w widget $data(-parent)
  96.     wm title $w $data(-title)
  97.  
  98.     # Set a grab and claim the focus too.
  99.  
  100.     ::tk::SetFocusGrab $w $data(ent)
  101.     $data(ent) delete 0 end
  102.     $data(ent) insert 0 $data(selectPath)
  103.     $data(ent) selection range 0 end
  104.     $data(ent) icursor end
  105.  
  106.     # Wait for the user to respond, then restore the focus and
  107.     # return the index of the selected button.  Restore the focus
  108.     # before deleting the window, since otherwise the window manager
  109.     # may take the focus away so we can't redirect it.  Finally,
  110.     # restore any grab that was in effect.
  111.  
  112.     vwait ::tk::Priv(selectFilePath)
  113.  
  114.     ::tk::RestoreFocusGrab $w $data(ent) withdraw
  115.  
  116.     # Cleanup traces on selectPath variable
  117.     #
  118.  
  119.     foreach trace [trace info variable data(selectPath)] {
  120.     trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
  121.     }
  122.     $data(dirMenuBtn) configure -textvariable {}
  123.  
  124.     # Return value to user
  125.     #
  126.     
  127.     return $Priv(selectFilePath)
  128. }
  129.  
  130. # ::tk::dialog::file::chooseDir::Config --
  131. #
  132. #    Configures the Tk choosedir dialog according to the argument list
  133. #
  134. proc ::tk::dialog::file::chooseDir::Config {dataName argList} {
  135.     upvar ::tk::dialog::file::$dataName data
  136.  
  137.     # 0: Delete all variable that were set on data(selectPath) the
  138.     # last time the file dialog is used. The traces may cause troubles
  139.     # if the dialog is now used with a different -parent option.
  140.     #
  141.     foreach trace [trace info variable data(selectPath)] {
  142.     trace remove variable data(selectPath) [lindex $trace 0] [lindex $trace 1]
  143.     }
  144.  
  145.     # 1: the configuration specs
  146.     #
  147.     set specs {
  148.     {-mustexist "" "" 0}
  149.     {-initialdir "" "" ""}
  150.     {-parent "" "" "."}
  151.     {-title "" "" ""}
  152.     }
  153.  
  154.     # 2: default values depending on the type of the dialog
  155.     #
  156.     if {![info exists data(selectPath)]} {
  157.     # first time the dialog has been popped up
  158.     set data(selectPath) [pwd]
  159.     }
  160.  
  161.     # 3: parse the arguments
  162.     #
  163.     tclParseConfigSpec ::tk::dialog::file::$dataName $specs "" $argList
  164.  
  165.     if {$data(-title) eq ""} {
  166.     set data(-title) "[mc "Choose Directory"]"
  167.     }
  168.     
  169.     # Stub out the -multiple value for the dialog; it doesn't make sense for
  170.     # choose directory dialogs, but we have to have something there because we
  171.     # share so much code with the file dialogs.
  172.     set data(-multiple) 0
  173.  
  174.     # 4: set the default directory and selection according to the -initial
  175.     #    settings
  176.     #
  177.     if {$data(-initialdir) ne ""} {
  178.     # Ensure that initialdir is an absolute path name.
  179.     if {[file isdirectory $data(-initialdir)]} {
  180.         set old [pwd]
  181.         cd $data(-initialdir)
  182.         set data(selectPath) [pwd]
  183.         cd $old
  184.     } else {
  185.         set data(selectPath) [pwd]
  186.     }
  187.     }
  188.  
  189.     if {![winfo exists $data(-parent)]} {
  190.     error "bad window path name \"$data(-parent)\""
  191.     }
  192. }
  193.  
  194. # Gets called when user presses Return in the "Selection" entry or presses OK.
  195. #
  196. proc ::tk::dialog::file::chooseDir::OkCmd {w} {
  197.     upvar ::tk::dialog::file::[winfo name $w] data
  198.  
  199.     # This is the brains behind selecting non-existant directories.  Here's
  200.     # the flowchart:
  201.     # 1.  If the icon list has a selection, join it with the current dir,
  202.     #     and return that value.
  203.     # 1a.  If the icon list does not have a selection ...
  204.     # 2.  If the entry is empty, do nothing.
  205.     # 3.  If the entry contains an invalid directory, then...
  206.     # 3a.   If the value is the same as last time through here, end dialog.
  207.     # 3b.   If the value is different than last time, save it and return.
  208.     # 4.  If entry contains a valid directory, then...
  209.     # 4a.   If the value is the same as the current directory, end dialog.
  210.     # 4b.   If the value is different from the current directory, change to
  211.     #       that directory.
  212.  
  213.     set selection [tk::IconList_CurSelection $data(icons)]
  214.     if {[llength $selection] != 0} {
  215.     set iconText [tk::IconList_Get $data(icons) [lindex $selection 0]]
  216.     set iconText [file join $data(selectPath) $iconText]
  217.     Done $w $iconText
  218.     } else {
  219.     set text [$data(ent) get]
  220.     if {$text eq ""} {
  221.         return
  222.     }
  223.     set text [file join {*}[file split [string trim $text]]]
  224.     if {![file exists $text] || ![file isdirectory $text]} {
  225.         # Entry contains an invalid directory.  If it's the same as the
  226.         # last time they came through here, reset the saved value and end
  227.         # the dialog.  Otherwise, save the value (so we can do this test
  228.         # next time).
  229.         if {$text eq $data(previousEntryText)} {
  230.         set data(previousEntryText) ""
  231.         Done $w $text
  232.         } else {
  233.         set data(previousEntryText) $text
  234.         }
  235.     } else {
  236.         # Entry contains a valid directory.  If it is the same as the
  237.         # current directory, end the dialog.  Otherwise, change to that
  238.         # directory.
  239.         if {$text eq $data(selectPath)} {
  240.         Done $w $text
  241.         } else {
  242.         set data(selectPath) $text
  243.         }
  244.     }
  245.     }
  246.     return
  247. }
  248.  
  249. # Change state of OK button to match -mustexist correctness of entry
  250. #
  251. proc ::tk::dialog::file::chooseDir::IsOK? {w text} {
  252.     upvar ::tk::dialog::file::[winfo name $w] data
  253.  
  254.     set ok [file isdirectory $text]
  255.     $data(okBtn) configure -state [expr {$ok ? "normal" : "disabled"}]
  256.  
  257.     # always return 1
  258.     return 1
  259. }
  260.  
  261. proc ::tk::dialog::file::chooseDir::DblClick {w} {
  262.     upvar ::tk::dialog::file::[winfo name $w] data
  263.     set selection [tk::IconList_CurSelection $data(icons)]
  264.     if {[llength $selection] != 0} {
  265.     set filenameFragment \
  266.         [tk::IconList_Get $data(icons) [lindex $selection 0]]
  267.     set file $data(selectPath)
  268.     if {[file isdirectory $file]} {
  269.         ::tk::dialog::file::ListInvoke $w [list $filenameFragment]
  270.         return
  271.     }
  272.     }
  273. }
  274.  
  275. # Gets called when user browses the IconList widget (dragging mouse, arrow
  276. # keys, etc)
  277. #
  278. proc ::tk::dialog::file::chooseDir::ListBrowse {w text} {
  279.     upvar ::tk::dialog::file::[winfo name $w] data
  280.  
  281.     if {$text eq ""} {
  282.     return
  283.     }
  284.  
  285.     set file [::tk::dialog::file::JoinFile $data(selectPath) $text]
  286.     $data(ent) delete 0 end
  287.     $data(ent) insert 0 $file
  288. }
  289.  
  290. # ::tk::dialog::file::chooseDir::Done --
  291. #
  292. #    Gets called when user has input a valid filename.  Pops up a
  293. #    dialog box to confirm selection when necessary. Sets the
  294. #    Priv(selectFilePath) variable, which will break the "vwait"
  295. #    loop in tk_chooseDirectory and return the selected filename to the
  296. #    script that calls tk_getOpenFile or tk_getSaveFile
  297. #
  298. proc ::tk::dialog::file::chooseDir::Done {w {selectFilePath ""}} {
  299.     upvar ::tk::dialog::file::[winfo name $w] data
  300.     variable ::tk::Priv
  301.  
  302.     if {$selectFilePath eq ""} {
  303.     set selectFilePath $data(selectPath)
  304.     }
  305.     if {$data(-mustexist) && ![file isdirectory $selectFilePath]} {
  306.     return
  307.     }
  308.     set Priv(selectFilePath) $selectFilePath
  309. }
  310.